CUBE CONNECT Edition Help

Important Note on using CubePy Methods from an Object that is not captured in a Variable

The user should be aware of a problem related to using the result of a method call that is not captured in a variable. The issue occurs when a method that returns an object is called in the first place, and then, a method is directly called on that returned object, without capturing that object in a variable.

This problem is related to the lifetime of the objects and the interaction between Python and SWIG, with "garbage collection" of parent objects, that will make them not available.

The user needs to capture returned values of objects into variables, before accessing the "attributes" or "child objects" of that returned object (the parent), either by using a variable name or store the parent in a list, dictionary, etc, to avoid obtaining incorrect results from child methods.

Some examples are provided in the remaining of the paragraph.

The first example shows the correct implementation, where the result of the db.metadata() call is a CubeDatabaseMetadata object, which is stored in a variable. The variable is then used to call child methods providing the size of the object in terms of number of networks contained in the SQLite database.

source_db = "D:/Cubetown.SQLite"
db = cp.CubeDatabase(source_db)
metadata_objects = db.metadata()  # parent captured in a variable
size_metadata = metadata_objects.networks.size()

The second example below shows the incorrect implementation, where the db.metadata() result is not stored in a variable, but it is used directly to call the child method. The result, in this case, will be incorrect, with a returned value for the size of zero.

source_db = "D:/Cubetown.SQLite"
db = cp.CubeDatabase(source_db)
size_metadata = db.metadata().networks.size()

Another example stores the results of the parent method in a list for db.networkMetadata(). The result for db.networkMetadata() is a CubeNetworkMetadata object with several child methods. Since we store the parent method as a first element of a list called metadata_list, we can call the child method linkAttributes, generating a vector with the link attributes, and size() providing its size.

source_db = "D:/Cubetown.SQLite"
db = cp.CubeDatabase(source_db)
metadata_list = [db.networkMetadata("Highway")]  # parent captured 
numb_of_attributes = metadata_list[0].linkAttributes.size()

An incorrect implementation would be to store in a list entry (or in a variable) not the parent method object, but the child element (linkAttributes). This incorrect implementation will return a zero value.

source_db = "D:/Cubetown.SQLite"
db = cp.CubeDatabase(source_db)
metadata_list = [db.networkMetadata("Highway").linkAttributes]
numb_of_attributes = metadata_list[0].size()